<template>
  <FormItem :label="label" single :prop="prop">
    <input v-show="false" :disabled="isLoading" ref="inputFile" type="file" :accept="accept" @change="add($event)"
      :multiple="multiple" />
    <div>
      <h-button icon="h-icon-upload" :loading="isLoading" @click="fileChange" :disabled="see">附件上传</h-button>
      <div style="height: 4px;"></div>
      <Table :datas="datas" v-if="datas.length > 0 && showHis" :border="true" :isStripe="true">
        <TableItem title="原始名称" prop="originalName" />
        <TableItem title="文件路径" prop="newName" />
        <TableItem title="操作" :width="130" fixed="right">
          <template #default="{ data }">
            <span class="link" @click="preview(data)">查看</span>
            <Space :width="16" />
            <span class="link" @click="download(data)">下载</span>
            <Space :width="16" />
            <span class="link" @click="deleteFile(data)">删除</span>
          </template>
        </TableItem>
      </Table>
    </div>
  </FormItem>
</template>

<script>
import { message, confirm, imagePreview } from 'heyui';

export default {
  name: "FormUpload",
  props: {
    modelValue: {
      type: String,
      default: ""
    },
    showHis: {
      type: Boolean,
      default: true
    },
    uploadUrl: {
      type: String,
      default: "/system/secure/minio/uploadFile",
      required: true
    },
    isSecure: {
      type: Boolean,
      default: true
    },
    showUrl: {
      default: "/system/secure/minio/getPreview",
      type: String
    },
    downloadUrl: {
      default: "/system/secure/minio/getUrl",
      type: String
    },
    deleteUrl: {
      type: String,
      default: "/system/secure/minio/delete"
    },
    accept: {
      type: String,
      default: ""
    },
    multiple: {
      type: Boolean,
      default: false
    },
    name: {
      type: String,
      default: "file"
    },
    params: {
      type: Object,
      default: null
    },
    success: {
      type: String,
      default: "success"
    },
    label: {
      type: String,
      default: ""
    },
    prop: {
      type: String,
      default: ""
    }
  },
  data() {
    return {
      datas: [],
      selected: "",
      isLoading: false,
      file: [],
    };
  },
  watch: {
    modelValue(newValue) {
      this.pushFile(newValue);
    }
  },
  computed: {
    see() {
      return this.$store.forms.see;
    }
  },
  methods: {
    pushFile(newValue) {
      let parsed;
      try {
        parsed = JSON.parse(newValue);
      } catch (e) {
        console.error(e)
        return;
      }
      if (Array.isArray(parsed)) {
        parsed.forEach(item => {
          let fileExists = this.datas.some(file => file.newName === item.newName);
          if (!fileExists) {
            this.datas.push(item)
          }
        });
      } else {
        let fileExists = this.datas.some(file => file.newName === parsed.newName);
        console.log(parsed, this.datas);
        if (!fileExists) {
          this.datas.push(parsed)
        }
      }
    },
    fileChange() {
      if (!this.multiple && this.datas.length != 0) {
        message.warn("该输入项不支持多文件上传，请删除后重新上传！");
        return;
      }
      this.$refs.inputFile.click();
    },
    add(event) {
      this.file = event.target.files;
      const names = [];
      for (let i = 0; i < this.file.length; i++) {
        names.push(this.file[i].name);
      }
      this.selected = names.join(",");
      this.uploadFile(event);
    },
    uploadFile(event) {
      event.preventDefault();
      this.isLoading = true;
      const formData = new FormData();
      for (let i = 0; i < this.file.length; i++) {
        formData.append(this.name, this.file[i]);
      }
      if (this.params) {
        for (const key in this.params) {
          formData.append(key, this.params[key] || "");
        }
      }
      this.$upload(this.uploadUrl, formData).then(res => {
        this.isLoading = false;
        if (res.data.code == 200) {
          message.info("上传成功");
          this.file = [];
          this.pushFile(JSON.stringify(res.data.data))
          this.$emit('update:modelValue', JSON.stringify(this.datas)); // 触发 v-model 的更新
          this.$emit(this.success, res.data.data);
        } else {
          message.error(res.data.msg);
        }
      }).catch(err => {
        this.isLoading = false;
        message.error(err);
      });
    },
    download(data) {
      confirm({
        content: '确定下载文件？',
        onConfirm: () => {
          if (this.isSecure) {
            this.$get(this.downloadUrl, { mediaUrl: data.newName, originalName: data.originalName }).then(res => {
              const link = document.createElement('a');
              link.href = res.data;
              link.download = data.originalName;
              document.body.appendChild(link);
              link.click();
              document.body.removeChild(link);
            });
          } else {
            const link = document.createElement('a');
            link.href = this.$store.dicts["minioUrl"][0].value + "/" + data.newName;
            link.download = data.originalName;
            document.body.appendChild(link);
            link.click();
            document.body.removeChild(link);
          }
        }
      });
    },
    preview(data) {
      if (this.isSecure) {
        this.$get(this.showUrl, { mediaUrl: data.newName, originalName: data.originalName }).then(res => {
          console.log(res.data)
          if (this.isImage(res.data)) {
            imagePreview(res.data);
          } else if ((data.originalName.endsWith(".pdf") && res.data.includes('.pdf'))) {
            window.open(res.data, '_blank');
          } else {
            message.warn('不支持该类型文件查看');
          }
        });
      } else {
        if (this.isImage(data.newName)) {
          imagePreview(this.$store.dicts["minioUrl"][0].value + "/" + data.newName);
        } else if (data.originalName.endsWith(".pdf") && data.newName.includes('.pdf')) {
          window.open(res.data, '_blank');
        } else {
          message.warn('不支持该类型文件查看');
        }
      }
    },
    deleteFile(data) {
      confirm({
        content: '确定删除？',
        onConfirm: () => {
          this.$postForm(this.deleteUrl, { mediaUrl: data.newName }).then(res => {
            if (res.data.code == 200) {
              this.datas = this.datas.filter(item => item.newName !== data.newName);
              this.$emit('update:modelValue', JSON.stringify(this.datas));
            } else {
              message.error(res.data.msg);
            }
          });
        }
      });
    },
    isImage(filename) {
      const imageExtensions = ['.jpg', '.jpeg', '.png', '.gif', '.bmp', '.webp', '.svg', '.tiff'];
      for (let i = 0; i < imageExtensions.length; i++) {
        if (filename.includes(imageExtensions[i])) {
          return true
        }
      }
    }
  }
};
</script>
